﻿/*
 * This file is part of quickReminder, a software for gamers
 *
 * Copyright (C) 2006-2009 Lucas Romero
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;


namespace LucasCode.PublicTypes
{
    public class ConsoleParserHL1 : ConsoleParserBase
    {
        static ConsoleParserHL1()
        {
            WeaponDict.Add("ak47", MatchWeapons.AK47);
            WeaponDict.Add("aug", MatchWeapons.Aug);
            WeaponDict.Add("xm1014", MatchWeapons.AutoShotgun);
            WeaponDict.Add("awp", MatchWeapons.AWP);
            WeaponDict.Add("deagle", MatchWeapons.DesertEagle);
            WeaponDict.Add("elite", MatchWeapons.DualElite);
            WeaponDict.Add("famas", MatchWeapons.Famas);
            WeaponDict.Add("fiveseven", MatchWeapons.FiveSeven);
            WeaponDict.Add("g3sg1", MatchWeapons.G3);
            WeaponDict.Add("galil", MatchWeapons.Galil);
            WeaponDict.Add("glock18", MatchWeapons.Glock);
            WeaponDict.Add("m249", MatchWeapons.M249);
            WeaponDict.Add("m3", MatchWeapons.M3);
            WeaponDict.Add("m4a1", MatchWeapons.M4A1);
            WeaponDict.Add("mac10", MatchWeapons.Mac10);
            WeaponDict.Add("mp5navy", MatchWeapons.MP5);
            WeaponDict.Add("p228", MatchWeapons.P228);
            WeaponDict.Add("p90", MatchWeapons.P90);
            WeaponDict.Add("scout", MatchWeapons.Scout);
            WeaponDict.Add("sg550", MatchWeapons.SG550);
            WeaponDict.Add("sg552", MatchWeapons.Sig);
            WeaponDict.Add("tmp", MatchWeapons.TMP);
            WeaponDict.Add("ump45", MatchWeapons.UMP45);
            WeaponDict.Add("usp", MatchWeapons.USP);
            WeaponDict.Add("worldspawn", MatchWeapons.Worldspawn);
            WeaponDict.Add("grenade", MatchWeapons.Grenade);
            WeaponDict.Add("knife", MatchWeapons.Knife);
        }

        static readonly Regex UserRegex = new Regex(@"#\s*\d+\s+""(?<name>.+?)""\s+\d+\s+STEAM_(?<steamid>\d+:\d+:\d+)");
        /* status map info:
          * map     :  scoutmap at: -1164 x, 210 y, -26 z
          * */
        static readonly Regex MapRegex = new Regex(@"map\s+:\s+(.*?)\s+at: -?\d+ x, -?\d+ y, -?\d+ z");

        static readonly Regex NameRegex = new Regex(@"^\* (?<from>.*?) changed name to (?<to>.*?)$");
        static readonly Regex KillRegex = new Regex(@"^(?<killer>.*?) killed (?<killee>.*?) with (?<weapon>.*?)$");
        static readonly Regex KillHSRegex = new Regex(@"^\*\*\* (?<killer>.*?) killed (?<killee>.*?) with a headshot from (?<weapon>.*?) \*\*\*$");
        static readonly Dictionary<string, MatchWeapons> WeaponDict = new Dictionary<string, MatchWeapons>();
        /*
         James Bond 006 Licence pending killed Sigourney Weaver with deagle
         Parsing: *** HI-EMP . Str!K3r.#^) killed Robert DeNiro with a headshot from usp ***
         */

        public override void Parse(ConsoleEventItem ev, MatchArchive archive, bool countKills)
        {
            System.Diagnostics.Debug.WriteLine("Parsing: " + ev.EventText);

            foreach (Match m in UserRegex.Matches(ev.EventText))
            {
                // get already sets the information we want to set, so just "get it"
                MatchPlayer p = archive.getPlayer(m.Groups["name"].Value, null, m.Groups["steamid"].Value, true);
            }
            
            Match match;
            if ((match = MapRegex.Match(ev.EventText)).Success)
            {
                // TODO: set current map
            }
            if ((match = NameRegex.Match(ev.EventText)).Success)
            {
                MatchPlayer p = archive.getPlayer(match.Groups["from"].Value, null, null, false);
                if (p != null)
                    p.CurrentNick = match.Groups["to"].Value;
            }
            else if (countKills)
            {
                if ((match = KillHSRegex.Match(ev.EventText)).Success)
                {
                    MatchPlayer Killer, Killee;
                    Killer = archive.getPlayer(match.Groups["killer"].Value, null, null, true);
                    Killee = archive.getPlayer(match.Groups["killee"].Value, null, null, true);
                    MatchWeapons weapon = MatchWeapons.None;
                    try
                    {
                        weapon = WeaponDict[match.Groups["weapon"].Value];

                    }
                    catch
                    {
                        System.Diagnostics.Trace.WriteLine(@"Couldn't find matchweapon " + match.Groups["weapon"].Value + " in WeaponDict");
                    }
                    //TODO: is this the best way to handle selfkills?
                    if (weapon != MatchWeapons.Worldspawn)
                    {
                        Killee.AddAction(new MatchAction(MatchActions.Dies, Killee.QrID, Killer.QrID, weapon, true));
                        Killer.AddAction(new MatchAction(MatchActions.Kills, Killer.QrID, Killee.QrID, weapon, true));
                    }
                    else
                    {
                        Killer.AddAction(new MatchAction(MatchActions.Dies, Killee.QrID, -1, weapon, true));
                    }
                }
                else if ((match = KillRegex.Match(ev.EventText)).Success)
                {
                    MatchPlayer Killer, Killee;
                    Killer = archive.getPlayer(match.Groups["killer"].Value, null, null, true);
                    Killee = archive.getPlayer(match.Groups["killee"].Value, null, null, true);
                    MatchWeapons weapon = MatchWeapons.None;
                    try
                    {
                        weapon = WeaponDict[match.Groups["weapon"].Value];

                    }
                    catch
                    {
                        System.Diagnostics.Trace.WriteLine(@"Couldn't find matchweapon " + match.Groups["weapon"].Value + " in WeaponDict");
                    }
                    //TODO: is this the best way to handle selfkills?
                    if (weapon != MatchWeapons.Worldspawn)
                    {
                        Killee.AddAction(new MatchAction(MatchActions.Dies, Killee.QrID, Killer.QrID, weapon, false));
                        Killer.AddAction(new MatchAction(MatchActions.Kills, Killer.QrID, Killee.QrID, weapon, false));
                    }
                    else
                    {
                        Killer.AddAction(new MatchAction(MatchActions.Dies, Killee.QrID, -1, weapon, false));
                    }
                }
            }
        }
    }
}